package Calculadora.Stack.StackList;

/**
 * Implementacion de stack con Lista Circular
 * @param <E>  clase generica
 * @author Douglas Davila
 * @since 12/08/2012
 * @version 1.0
 * @see List
 */
public class CircularList<E> extends AbstractList<E>{
    /**Cantidad de objetos en la lista*/ 
    protected int count;
    /**Referencia a la cola de la lista*/
    protected SinglyLinkedListElement tail;
    
    /**
    * Contructor
    * @pre: N/A
    * @post: genera una lista nueva y vacia
    * @since 12/08/2012
    */
    public CircularList(){
        tail = null;
        count = 0;
    }
    
    /**
    * Determina la cantidad de objetos de la lista
    * @return cantidad de objetos de la lista
    * @pre N/A
    * @post retorna la cantidad de objetos de la lista
    * @since 12/08/2012
    * @see List
    */
    @Override
    public int size(){
        return count;
    }  
    
    /**
    * Agrega un objeto al inico de la lista
    * @param item El objeto a agregar a la lista
    * @pre N/A
    * @post El objeto es agregado al inicio de la lista
    * @since 12/08/2012
    * @see List
    */
    @Override
    public void addFirst(E item){
        SinglyLinkedListElement temp = new SinglyLinkedListElement(item);
        if (tail == null) { 
            tail = temp;
            tail.setNext(tail);
        } 
        else { 
            temp.setNext(tail.next());
            tail.setNext(temp);
        }
        count++;
   }
    
    /**
     * Se obtiene la referencia del primer objeto en la lista
     * @return la referencia del primer objeto en la lista
     * @pre que la lista no este vacia
     * @post retorna la referencia del primero objeto en la lista
     * @since 12/08/2012
     * @see List
     */
    @Override
    public E getFirst(){
        return (E) tail.next().value();
    }

    /**
     * Se remueve el primer objeto en la lista
     * @return El primer objeto en la lista
     * @pre que la lista no este vacia
     * @post se remueve el primer objeto en la lista
     * @since 12/08/2012
     * @see List
     */
    @Override
    public E removeFirst(){
        SinglyLinkedListElement temp = tail.next(); 
        if (tail == tail.next()) {
            tail = null;
        } 
        else {
            tail.setNext(temp.next());
            temp.setNext(null); 
        }
        count--;
        return (E) temp.value();
    } 
}
